﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using taigu.WebChat;
using taigu.WeChat;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Security.Encryption;

namespace taigu
{
    //[Authorize]
    public class WeChatUserService : CrudAppService<
        WeChat.WeChatUsers,
            WeChat.WeChatUserDto, //Used to show books
             Guid, //Primary key of the book entity
             PagedAndSortedResultRequestDto, //Used for paging/sorting
             WeChat.CreateUpdateWeChatUserDto>, //Used to create/update a book
         IWeChatUserService
    {
        public IRepository<WeChatUsers, Guid> _WeChatuser;
        public IRepository<PostInfo, Guid> _postinfo;
        public IRepository<Draw_log, Guid> _draw_log;
        public IRepository<Address, Guid> _addresses;
        private readonly IRepository<Awards, Guid> _awards;
        private readonly IRepository<db_task, int> _db_Tasks;
        IStringEncryptionService _stringEncryptionService;
        public WeChatUserService(IRepository<WeChat.WeChatUsers, Guid> repository, IConfiguration configuration, IRepository<WeChatUsers, Guid> WeChatuser, IRepository<PostInfo, Guid> postinfo, IRepository<Draw_log, Guid> draw_log, IRepository<Address, Guid> addresses, IRepository<Awards, Guid> awards, IStringEncryptionService stringEncryptionService, IRepository<db_task, int> db_Tasks)
           : base(repository)
        {
            this._configuration = configuration;
            _WeChatuser = WeChatuser;
            _postinfo = postinfo;
            _draw_log = draw_log;
            _addresses = addresses;
            this._awards = awards;
            _db_Tasks = db_Tasks;
            _stringEncryptionService = stringEncryptionService;
        }
        private IConfiguration _configuration;

        /// <summary>
        /// 通过微信login的code获取token
        /// </summary>
        /// <param name="code">微信小程序登录之后的code</param>
        /// <returns>ResData<string></returns>
        [AllowAnonymous]
        [Route("/wechat/login"), HttpPost]
        public async Task<ResData<object>> GetLogin(WechatDto m)
        {
            try
            {
                string x = _stringEncryptionService.Encrypt("1q2w3E*");
                string s = _stringEncryptionService.Decrypt(x);

                //获取微信小程序配置
                var appId = _configuration.GetSection("WxConfig:appId").Value;
                var appSecret = _configuration.GetSection("WxConfig:appSecret").Value;
                var grant_type = _configuration.GetSection("WxConfig:grant_type").Value;
                var appUserName = _configuration.GetSection("WxConfig:appUserName").Value;//默认后台授权帐号
                var appUserPwd = _configuration.GetSection("WxConfig:appUserPwd").Value;//默认后台授权帐号密码

                var client = new HttpClient();
                var res = client.GetAsync($"https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={appSecret}&js_code={m.code}&grant_type={grant_type}");
                Task<string> result = res.Result.Content.ReadAsStringAsync();
                dynamic wxRes = JObject.Parse(result.Result);
                string openId = wxRes?.openid?.ToString();
                string tokenKey = wxRes?.session_key?.ToString();


                // if (!string.IsNullOrEmpty(openId))//表示用户微信授权成功
                if (string.IsNullOrEmpty(openId))//表示用户微信授权成功
                {
                    // openId = "sfdds";
                    //同步数据库
                    WeChat.WeChatUsers WeChatUserDto = base.Repository.FirstOrDefault(x => x.open_id == openId.ToString());
                    if (WeChatUserDto == null)
                    {
                        WeChat.CreateUpdateWeChatUserDto dto = new WeChat.CreateUpdateWeChatUserDto();
                        dto.open_id = openId;
                        dto.status = UserStatus.enabled;
                        dto.user_type = UserType.亲友团;
                        WeChat.WeChatUserDto getOutputDto = await base.CreateAsync(dto);
                    }
                    //代码要处理上面的getoupputDto是否是新加的数据的实例，userId
                    WeChatUserDto = base.Repository.FirstOrDefault(x => x.open_id == openId.ToString());
                    Ids4Service ids4Service = new Ids4Service(_configuration);
                    string token = await ids4Service.GetIdsTokenAsync(appUserName, appUserPwd);
                    if (string.IsNullOrEmpty(token))
                    {
                        return ResData<object>.Error("后台接口授权失败", null, ResStatus.微信端接口错误);
                    }
                    dynamic info = new { token = token, open_id = openId, user_id = WeChatUserDto.Id };
                    return new ResData<object>() { Status = ResStatus.成功, Msg = "获取token成功", Info = info };
                }
                else
                {
                    return ResData<object>.Error("后台接口授权失败", null, ResStatus.微信端接口错误);
                }
            }
            catch (Exception ex)
            {
                return ResData<object>.Error(string.Empty, ex, ResStatus.微信端接口错误);
            }
        }
        [Route("/wechat/getUserInfo"), HttpPost]
        public async Task<ResData<object>> GetUserInfo(WebChat.WechatDto m)
        {
            WeChat.WeChatUsers WeChatUserDto = null;


            //同步数据库
            await Task.Run(() =>
            {

                WeChatUserDto = base.Repository.FirstOrDefault(x => x.Id == m.user_id);


            });

            // return ResData<object>.Error(ResStatus.非法操作.ToString(), null, ResStatus.员工号不存在);
            if (WeChatUserDto == null)
            {
                return ResData<object>.Error("获取用户信息失败", null, ResStatus.查询失败);
            }
            else
            {
                var resModel = ObjectMapper.Map<WeChat.WeChatUsers, WeChat.WeChatUserInfoDto>(WeChatUserDto);
                //获取当前用户的是否有地址数据
                resModel.haveAddress = _addresses?.Where(x => x.user_id == m.user_id).Count() > 0 ? true : false;

                return new ResData<object>() { Status = ResStatus.成功, Msg = "success", Info = resModel };
            }
        }
        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [Route("/wechat/createUser"), HttpPost]
        public async Task<ResData<object>> CreateUser(WeChat.CreateWeChatUserDto dto)
        {
            WeChat.WeChatUsers WeChatUserDto = null;

            //获取当前openid的用户
            await Task.Run(() =>
            {
                WeChatUserDto = base.Repository.FirstOrDefault(x => x.open_id == dto.open_id.ToString());
            });

            // return ResData<object>.Error(ResStatus.非法操作.ToString(), null, ResStatus.员工号不存在);
            if (WeChatUserDto == null)
            {
                WeChat.CreateUpdateWeChatUserDto insertDto = ObjectMapper.Map<WeChat.CreateWeChatUserDto, WeChat.CreateUpdateWeChatUserDto>(dto);
                insertDto.status = UserStatus.enabled;//2021-11-27设置用户注册时为可用
                WeChat.WeChatUserDto getOutputDto = await base.CreateAsync(insertDto);
                return ResData<object>.Error("成功", null, ResStatus.成功);
            }
            else
            {
                //将CreateWeChatUserDto转换成CreateUpdateWeChatUserDto
                WeChat.CreateUpdateWeChatUserDto updateDto = ObjectMapper.Map<WeChat.CreateWeChatUserDto, WeChat.CreateUpdateWeChatUserDto>(dto);
                updateDto.status = UserStatus.enabled;//2021-11-29设置用户注册时为可用
                WeChat.WeChatUserDto getOutputDto = await base.UpdateAsync(WeChatUserDto.Id, updateDto);
                return new ResData<object>() { Status = ResStatus.成功, Msg = "sucess", Info = { } };
            }
        }

        /// <summary>
        /// 获取自己当日获得的总抽奖次数及剩余抽奖次数
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [Route("/wechat/getDrawCount/"), HttpPost]
        public async Task<ResData<object>> GetDrawCount(WebChat.UserDto dto)
        {
            //PostInfo发帖数量
            //WeChatUsers UserType 用户表 判断员工
            int maxCount = 0;
            int rest = 0;
            bool isDrawed = false;
            await Task.Run(() =>
            {
                rest = rest <= 0 ? 0 : rest;
                GetUserDrawCount(dto, out maxCount, out rest, out isDrawed);
                if (isDrawed)
                {
                    return new ResData<object> { Info = new { total = maxCount, rest = 0 }, Msg = "当天抽奖次数已用完", Status = ResStatus.成功 };
                }
                else
                {
                    return new ResData<object> { Info = new { total = maxCount, rest = rest }, Msg = "success", Status = ResStatus.成功 };

                }
            });
            return new ResData<object> { Info = new { total = maxCount, rest = rest }, Msg = "success", Status = ResStatus.成功 };
        }

        private void GetUserDrawCount(UserDto dto, out int maxCount, out int rest, out bool isDrawed)
        {
            maxCount = 0;
            rest = 0;
            isDrawed = false;

            var lists = _WeChatuser.Where(x => x.Id == dto.user_id).FirstOrDefault();//获取员工信息

            if (lists.user_type == UserType.员工 && lists.status == UserStatus.enabled)//判断是否为员工，或是用户状态是否为可用2021-11-27
            {
                var infos = _postinfo.Where(x => x.user_id == dto.user_id).ToList();//查询发帖信息
                var infocount = infos.Where(x => x.CreationTime.ToShortDateString() == System.DateTime.Now.ToShortDateString()).ToList().Count();//查询今日发帖次数
                if (infocount > 0)//发果发贴大于0
                {
                    maxCount = infocount >= 3 ? 3 : infocount;//最大发贴次数

                    //判断当前用户是否中过奖
                    var model = (from awards in _awards
                                 join awards_log in _draw_log
                               on awards.Id equals awards_log.awards_id
                                 where awards_log.user_id == dto.user_id
                                 select new
                                 {
                                     drawId = awards.Id,
                                     awardName = awards.name,
                                     awardImageUrl = awards.image_url,
                                     awardGrade = awards.grade,
                                     createTime = awards_log.CreationTime
                                 });
                    var res = model.Where(x => x.awardGrade < 4).FirstOrDefault();

                    if (res != null)//表示已经中奖
                    {
                        isDrawed = true;
                        // return new ResData<object> { Info = "", Msg = "已中过奖", Status = ResStatus.成功 };
                    }
                    else//判断当前用户当天已经抽了几次
                    {
                        int awardsCount = _draw_log.Where(x => x.user_id == dto.user_id && x.CreationTime.Year == System.DateTime.Now.Year && x.CreationTime.Month == DateTime.Now.Month && x.CreationTime.Day == DateTime.Now.Day).Count();
                        rest = maxCount - awardsCount;


                    }
                }
            }

            // return new ResData<object> { Info = new { total = 0, rest = 0 }, Msg = "success", Status = ResStatus.成功 };
        }

        [Route("/draw/getDraw"), HttpPost]
        public ResData<object> GetDraw(WebChat.UserDto dto)
        {
            try
            {
                var model = (from awards in _awards
                             join awards_log in _draw_log
                           on awards.Id equals awards_log.awards_id
                             where awards_log.user_id == dto.user_id
                             select new
                             {
                                 drawId = awards.Id,
                                 awardName = awards.name,
                                 awardImageUrl = awards.image_url,
                                 awardGrade = awards.grade,
                                 createTime = awards_log.CreationTime
                             });
                var res = model.Where(x => x.awardGrade < 4).FirstOrDefault();

                return new ResData<object>
                {
                    Info = res,
                    Msg = "success",
                    Status = ResStatus.成功
                };
            }
            catch
            {

            }
            return new ResData<object>
            {
                Info = { },
                Msg = "success",
                Status = ResStatus.成功
            };

        }

        /// <summary>
        /// 发起抽奖
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [Route("/draw/createDraw"), HttpPost]
        [AllowAnonymous]
        public async Task<ResData<object>> CreateDraw(WebChat.UserDto dto)
        {

            int maxCount = 0;
            int rest = 0;
            bool isDrawed = false;

            rest = rest <= 0 ? 0 : rest;
            GetUserDrawCount(dto, out maxCount, out rest, out isDrawed);

            if (isDrawed == false && rest > 0)
            {
                List<Awards> list = await _awards.GetListAsync();
                Awards model = null;
                Dictionary<int, string> valuePairs = new Dictionary<int, string>();
                int dataLeng = 0;
                foreach (var item in list)
                {
                    dataLeng = valuePairs.Count + 1;
                    int count = Convert.ToInt32(item.ratio * 1000);
                    for (int i = dataLeng; i < dataLeng + count; i++)
                    {
                        valuePairs.Add(i, item.Id.ToString());
                    }

                }

                Random r = new Random(unchecked((int)DateTime.Now.Ticks));
                int result = r.Next(0, valuePairs.Count - 1).GetHashCode();
                if (result < valuePairs.Count)
                {
                    string guid = string.Empty;
                    valuePairs.TryGetValue(result, out guid);
                    model = _awards.FirstOrDefault(x => x.Id.ToString() == guid);
                    if (model != null && model.rest > 0)
                    {
                        model.rest -= 1;
                        await _awards.UpdateAsync(model);
                        //处理抽奖日志
                        Draw_log draw_Log_m = new Draw_log();
                        draw_Log_m.user_id = dto.user_id;
                        draw_Log_m.awards_id = model.Id;//guid
                        draw_Log_m.status = PostStatus.启用;
                        draw_Log_m.CreationTime = System.DateTime.Now;
                        await _draw_log.InsertAsync(draw_Log_m);

                        return new ResData<object>
                        {
                            Info = new
                            {
                                drawId = model.Id,
                                awardName = model.name,
                                awardImageUrl = model.image_url,
                                awardGrade = model.grade
                            },
                            Msg = "success",
                            Status = ResStatus.成功
                        };
                    }

                }
            }
            //未种奖返回

            var m = _awards.FirstOrDefault(x => x.grade == 4);
            m.rest -= 1;
            await _awards.UpdateAsync(m);

            //处理抽奖日志
            Draw_log draw_Log = new Draw_log();
            draw_Log.user_id = dto.user_id;
            draw_Log.awards_id = m.Id;
            draw_Log.status = PostStatus.启用;
            draw_Log.CreationTime = System.DateTime.Now;
            await _draw_log.InsertAsync(draw_Log);
            return new ResData<object>
            {
                Info = new
                {
                    drawId = m.Id,
                    awardName = m.name,
                    awardImageUrl = m.image_url,
                    awardGrade = m.grade
                },
                Msg = "success",
                Status = ResStatus.成功
            }; ;
        }

        /// <summary>
        /// 发起抽奖
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [Route("/draw/createDrawTest"), HttpPost]
        [AllowAnonymous]
        public async Task<List<ResData<object>>> CreateDrawTest(WebChat.UserDto dto)
        {
            List<ResData<object>> resDatas = new List<ResData<object>>();

            //int maxCount = 1000;
            //for (int j = 0; j < maxCount; j++)
            //{


            //    int rest = 100;
            //    bool isDrawed = false;

            //    // rest = rest <= 0 ? 0 : rest;
            //    // GetUserDrawCount(dto, out maxCount, out rest, out isDrawed);

            //    if (isDrawed == false && rest > 0)
            //    {
            //        List<Awards> list = await _awards.GetListAsync();
            //        Awards model = null;
            //        Dictionary<int, string> valuePairs = new Dictionary<int, string>();
            //        int dataLeng = 0;
            //        foreach (var item in list)
            //        {
            //            dataLeng = valuePairs.Count + 1;
            //            int count = Convert.ToInt32(item.ratio * 1000);
            //            for (int i = dataLeng; i < dataLeng + count; i++)
            //            {
            //                valuePairs.Add(i, item.Id.ToString());
            //            }

            //        }

            //        Random r = new Random(unchecked((int)DateTime.Now.Ticks));
            //        int result = r.Next(0, valuePairs.Count - 1).GetHashCode();
            //        if (result < valuePairs.Count)
            //        {
            //            string guid = string.Empty;
            //            valuePairs.TryGetValue(result, out guid);
            //            model = _awards.FirstOrDefault(x => x.Id.ToString() == guid);
            //            if (model != null && model.rest > 0)
            //            {
            //                model.rest -= 1;
            //                await _awards.UpdateAsync(model);

            //                //处理抽奖日志
            //                Draw_log draw_Log_m = new Draw_log();
            //                draw_Log_m.user_id = dto.user_id.ToString();
            //                draw_Log_m.awards_id = guid;
            //                draw_Log_m.status = PostStatus.启用;
            //                draw_Log_m.CreationTime = System.DateTime.Now;
            //                await _draw_log.InsertAsync(draw_Log_m);

            //                resDatas.Add(
            //                 new ResData<object>
            //                {
            //                    Info = new
            //                    {
            //                        drawId = model.Id,
            //                        awardName = model.name,
            //                        awardImageUrl = model.image_url,
            //                        awardGrade = model.grade
            //                    },
            //                    Msg = "success",
            //                    Status = ResStatus.成功
            //                });
            //            }
            //            else

            //            {
            //                //未种奖返回

            //                var m = _awards.FirstOrDefault(x => x.grade == 4);
            //                m.rest -= 1;
            //                await _awards.UpdateAsync(m);

            //                //处理抽奖日志
            //                Draw_log draw_Log = new Draw_log();
            //                draw_Log.user_id = dto.user_id.ToString();
            //                draw_Log.awards_id = m.Id.ToString();
            //                draw_Log.status = PostStatus.启用;
            //                draw_Log.CreationTime = System.DateTime.Now;
            //                await _draw_log.InsertAsync(draw_Log);

            //                resDatas.Add(new ResData<object>
            //                {
            //                    Info = new
            //                    {
            //                        drawId = m.Id,
            //                        awardName = m.name,
            //                        awardImageUrl = m.image_url,
            //                        awardGrade = m.grade
            //                    },
            //                    Msg = "success",
            //                    Status = ResStatus.成功
            //                });
            //            }

            //        }
            //        else
            //        {
            //            //未种奖返回

            //            var m = _awards.FirstOrDefault(x => x.grade == 4);
            //            m.rest -= 1;
            //            await _awards.UpdateAsync(m);

            //            //处理抽奖日志
            //            Draw_log draw_Log = new Draw_log();
            //            draw_Log.user_id = dto.user_id.ToString();
            //            draw_Log.awards_id = m.Id.ToString();
            //            draw_Log.status = PostStatus.启用;
            //            draw_Log.CreationTime = System.DateTime.Now;
            //            await _draw_log.InsertAsync(draw_Log);

            //            resDatas.Add(new ResData<object>
            //            {
            //                Info = new
            //                {
            //                    drawId = m.Id,
            //                    awardName = m.name,
            //                    awardImageUrl = m.image_url,
            //                    awardGrade = m.grade
            //                },
            //                Msg = "success",
            //                Status = ResStatus.成功
            //            });
            //        }
            //    }
            //    else
            //    {
            //        //未种奖返回

            //        var m = _awards.FirstOrDefault(x => x.grade == 4);
            //        m.rest -= 1;
            //        await _awards.UpdateAsync(m);

            //        //处理抽奖日志
            //        Draw_log draw_Log = new Draw_log();
            //        draw_Log.user_id = dto.user_id.ToString();
            //        draw_Log.awards_id = m.Id.ToString();
            //        draw_Log.status = PostStatus.启用;
            //        draw_Log.CreationTime = System.DateTime.Now;
            //        await _draw_log.InsertAsync(draw_Log);

            //        resDatas.Add(new ResData<object>
            //        {
            //            Info = new
            //            {
            //                drawId = m.Id,
            //                awardName = m.name,
            //                awardImageUrl = m.image_url,
            //                awardGrade = m.grade
            //            },
            //            Msg = "success",
            //            Status = ResStatus.成功
            //        });
            //    }

            //}
            // return resDatas;
            await Task.Run(() =>
            {

            });
            return resDatas;
        }







        [HttpPost, Route("/wechat/hd/taskAdd")]
        [AllowAnonymous]
        public async Task<ResData<string>> db_taskAdd(Createdb_taskDTO dbtask)
        {
            //db_task db_Task = ObjectMapper.Map<Createdb_taskDTO, db_task>(dbtask);
            db_task model = new db_task();
            model.User_id = dbtask.User_id;
            model.TaskData = dbtask.TaskData;
            model.TaskType = dbtask.TaskType;
            model.CreateTime = dbtask.CreateTime;
            await _db_Tasks.InsertAsync(model);
            return new ResData<string>() { Status = ResStatus.成功, Msg = "sucess", Info = "" };
        }

        /// <summary>
        /// 按照时间查询最新数据
        /// </summary>
        /// <returns></returns>
        [HttpGet, Route("/wechat/hd/taskShow")]
        public object TemperatureShow()
        {
            var query = from a in _db_Tasks
                        where a.TaskType == "室温"
                        orderby a.CreateTime descending
                        select a;
            db_task indoorTemperature= query.FirstOrDefault();

             query = from a in _db_Tasks
                        where a.TaskType == "体温"
                        orderby a.CreateTime descending
                        select a;
            db_task bodyTemperature = query.FirstOrDefault();
            query = from a in _db_Tasks
                    where a.TaskType == "血氧"
                    orderby a.CreateTime descending
                    select a;
            db_task bloodOxygen = query.FirstOrDefault();
            query = from a in _db_Tasks
                    where a.TaskType == "血糖"
                    orderby a.CreateTime descending
                    select a;
            db_task bloodSugar = query.FirstOrDefault();
            return new
            {
                //室温
                indoorTemperature = indoorTemperature.TaskData,
                indoorTemperatureCreationTime = indoorTemperature.CreateTime,
                //体温数据
                bodyTemperature = bodyTemperature.TaskData,
                bodyTemperatureCreationTime = bodyTemperature.CreateTime,
                //血氧(VOC)
                bloodOxygen = bloodOxygen.TaskData,
                bloodOxygenCreationTime = bloodOxygen.CreateTime,
                //血糖(CO2)
                bloodSugar = bloodSugar.TaskData,
                bloodSugarCreationTime = bloodSugar.CreateTime
            };
        }
    }
}
